<?php
/*
 *  This file is part of Urd.
 *
 *  Urd is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *  Urd is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program. See the file "COPYING". If it does not
 *  exist, see <http://www.gnu.org/licenses/>.
 *
 * $LastChangedDate: 2008-07-15 00:09:39 +0200 (Tue, 15 Jul 2008) $
 * $Rev: 1295 $
 * $Author: gavinspearhead $
 * $Id: newsgroups.php 1295 2008-07-14 22:09:39Z gavinspearhead $
 */
define('ORIGINAL_PAGE', $_SERVER['PHP_SELF']);

$pathng = realpath(dirname(__FILE__));

require_once "$pathng/../functions/html_includes.php";
require_once "$pathng/../functions/periods.php";

function build_newsgroup_query(DatabaseConnection $db, $userID, &$retvals = NULL)
{
    global $LN;
	assert(is_numeric($userID));
	$order_options = array ('name', 'postcount', 'active', 'last_updated', 'expire', 'refresh_time', 'refresh_period');
	$order_dirs = array ('desc', 'asc', '');
	$minngsize = get_pref($db, 'minngsize', $userID);
	$cnt = count_active_ng($db);
	$begin = get_request('offset', 0);
	$perpage = get_maxperpage($db, $userID);
	$search = utf8_decode(trim(get_request('search')));

    if ($search == (html_entity_decode("<{$LN['search']}>")))
        $search = '';
	$search_all = get_request('search_all');
	$order = strtolower(get_request('order'));
	$order_dir = strtolower(get_request('order_dir'));
	if (!in_array($order, $order_options))
		$order = 'name';
	if (!in_array($order_dir, $order_dirs))
        $order_dir = '';
	$showall = get_request('unsubscribed', '0');
	$unsubscribed = ($cnt == 0 || $search != '') ? TRUE : FALSE;
	$retvals[0] = $unsubscribed;

	// Search google style:
	$Qsearch = '';
	$search = str_replace('*', ' ', $search);
	$keywords = explode(' ', $search);
	$search_type = $db->get_pattern_search_command('LIKE'); // get the operator we need for the DB LIKE for mysql or ~~* for postgres
	foreach ($keywords as $keyword) {
        $k = "%{$keyword}%";
        $db->escape($k, TRUE);
		$Qsearch .= " AND \"name\" $search_type $k ";
    }
	// Default = we show only active groups:
	if ($cnt != 0 && $search == '')
		$Qsearch .= ' AND "active"=\'1\' ';
	else if ($minngsize > 0 && $search_all != '') 
		$Qsearch .= " AND \"postcount\" > '$minngsize' ";

	$time = time();
	$query = '*, ' .
		'"last_updated" AS timestamp ' .
		'FROM groups ' .
		"WHERE 1=1 $Qsearch " .
		"ORDER BY $order $order_dir"; 

	$res = $db->select_query($query, $perpage, $begin);
	if ($res === FALSE)
		$res = array();

	return $res;
}


function build_newsgroup_query_total(DatabaseConnection $db, $userID)
{
	assert(is_numeric($userID));
    global $LN;
	$minngsize = get_pref($db, 'minngsize', $userID);
	$cnt = count_active_ng($db);
    $search = utf8_decode(trim(get_request('search')));

    if ($search == (html_entity_decode("<{$LN['search']}>")))
        $search = '';
	$search_all = get_request('search_all', '');

	// Search google style:
	$Qsearch = '';
	$search = str_replace('*', ' ', $search);
	$keywords = explode(' ', $search);
	$search_type = $db->get_pattern_search_command('LIKE'); // get the operator we need for the DB LIKE for mysql or ~~* for postgres
	foreach ($keywords as $keyword){
        $k = "%{$keyword}%";
        $db->escape($k, TRUE);
		$Qsearch .= " AND \"name\" $search_type $k ";
//		$Qsearch .= " AND \"name\" $search_type '%{$keyword}%' ";
    }
	// Default = we show only active groups:
	if ($cnt != 0 && $search == '')
		$Qsearch .= ' AND "active"=1 ';
	else if ($minngsize > 0 && $search_all != '')
		$Qsearch .= " AND \"postcount\" > $minngsize ";

	$query = "COUNT(\"name\") AS cnt FROM groups WHERE 1=1 $Qsearch";

	$res = $db->select_query($query);
	if ($res === FALSE) return FALSE;
	if (!isset($res[0]['cnt'])) return FALSE;
	return $res[0]['cnt'];
}


function build_newsgroup_skipper(DatabaseConnection $db, $userID)
{
	assert(is_numeric($userID));
    global $LN;

	// Normal size, if there are more pages, a 1st and/or last page indicator can be added:
	$size = SKIPPER_SIZE;

	$perpage = get_maxperpage($db, $userID);
	$offset  = post_form('offset', 0);
	$search  = utf8_decode(trim(get_request('search', '')));
    if ($search == (html_entity_decode("<{$LN['search']}>")))
        $search = '';
	$showall = get_request('unsubscribed', '0');
	if ($showall != '0') {
		$unsubscribed = TRUE;
		$unsub = 1;
	} else {
		$unsubscribed = FALSE;
		$unsub = 0;
	}

	// First get all the rows:
	$total = build_newsgroup_query_total($db, $userID);

	$totalpages = ceil($total / $perpage);		// Total number of pages.
	$activepage = ceil(($offset+1) / $perpage); 	// This is the page we're on. (+1 because 0/100 = page 1)

	$start = max($activepage - floor($size/2), 1);	// We start at 1 unless we're now on page 12, then we show page 2.
	$end = min($start + $size, $totalpages);	// We don't go beyond 'totalpages' ofcourse.
	$start = max($end - $size, 1);			// Re-check $start, in case the pagenumber is near the end

	$pages = array();
	for ($i = 1; $i <= $totalpages; $i++) {
		$thispage = array();
		$thispage['number'] = $i;
		$pageoffset = ($i - 1) * $perpage;          // For page 1, offset = 0.

		$url = $_SERVER['PHP_SELF'] . "?offset={$pageoffset}&unsubscribed={$unsub}&search={$search}";
		$url = htmlspecialchars($url);
		$thispage['url'] = $pageoffset;
		// distance is the distance from the current page, maximum of 5. Used to colour close pagenumbers:
		$thispage['distance'] = min(abs($activepage - $i), 5);
		$pages[] = $thispage;
	}
	return array($pages, $totalpages, $activepage);
}


function update_user_ng_info(DatabaseConnection $db, $userID)
{
	assert(is_numeric($userID));
	if (!isset($_POST['newsgroup']))
		return;
	foreach ($_POST['newsgroup'] as $id=>$on) {
		if (is_numeric($id) &&  strtolower($on) == 1) {
			$visible = isset ($_POST['visible'][$id]) ? 1 : 0;
			$minsetsize = isset ($_POST['minsetsize'][$id]) ? $_POST['minsetsize'][$id] : 0;
			$maxsetsize = isset ($_POST['maxsetsize'][$id]) ? $_POST['maxsetsize'][$id] : 0;
			$sql = "* from usergroupinfo WHERE \"groupid\"=$id AND \"userid\"=$userID";
			$res = $db->select_query($sql, 1);
			if ($res === FALSE)
				$sql = "INSERT INTO usergroupinfo (\"minsetsize\", \"maxsetsize\",\"visible\", \"groupid\", \"userid\") " .
					"VALUES ('$minsetsize', '$maxsetsize','$visible', '$id', '$userID')";
			else 
				$sql = "UPDATE usergroupinfo SET \"minsetsize\"='$minsetsize', \"visible\"='$visible', \"maxsetsize\"='$maxsetsize' " .
					"WHERE \"groupid\"=$id and \"userid\"='$userID'";

			$db->execute_query($sql);
		}
	}
}
$uprefs = load_config($db);
$uc = new urdd_client($uprefs['urdd_host'], $uprefs['urdd_port'],$userID);
$urdd_online = $uc->is_connected();


function update_ng_subscriptions (DatabaseConnection $db, $uc, $userID)
{
	assert(is_numeric($userID));
	global $periods, $LN, $uprefs;
    if (!$uc->is_connected())
        fatal_error($LN['urdddisabled']);
    $def_exp = $uprefs['default_expire_time'];
    $max_exp = $uprefs['maxexpire'];
	if (!isset($_POST['newsgroup']))
		return;
	foreach ($_POST['newsgroup'] as $id=>$on) {
		if (is_numeric($id)) {
			if ($on == 1 && isset( $_POST['period'][$id]) && isset($_POST['time1'][$id]) && isset( $_POST['time2'][$id]) && isset( $_POST['expire'][$id])) {
				$period = $_POST['period'][$id];
				$time1 = $_POST['time1'][$id];
				$time2 = $_POST['time2'][$id];
				$exp = $_POST['expire'][$id];
                if (!is_numeric($exp) || $exp == 0) 
                    $exp = $def_exp;
				if ($exp > $max_exp || $exp < 1) 
					fatal_error($LN['error_bogusexptime']);
				$period = $periods->get($period);
				if ($period === FALSE)
					throw new exception ($LN['error_invalidupdatevalue']);

				remove_schedule($db, $uc, $id, COMMAND_UPDATE);
				if ($period->interval !== NULL) {
					if (!is_numeric($time1)) fatal_error($LN['error_notanumber']);
					if (!is_numeric($time2)) fatal_error($LN['error_notanumber']);
					if ($time1 > 23 || $time1 < 0) fatal_error($LN['error_toomanydays']);
					if ($time2 > 59 || $time1 < 0) fatal_error($LN['error_toomanymins']);

					// Sanity checks:
					$time1 %= 24;
					$time2 %= 60;
					$time = $time1 * 60 + $time2; // Used to display the update time, is in mins after 0:00
					$nicetime = $time1 . ':' . $time2;
					//$next = $period->next .  ' ' . $nicetime;
					// if we have a proper schedule set it here
			
					set_period($uc, $db, $id, $nicetime, $period->interval, $time, $period->id);
				}
				// if it all works out, we also subscribe to the newsgroup
				$uc->subscribe($id, $exp);
			} else {
				$uc->cancel(get_command(COMMAND_UPDATE) . " $id");
				$uc->cancel(get_command(COMMAND_EXPIRE) . " $id");
				$uc->cancel(get_command(COMMAND_GENSETS) . " $id");
				$uc->unsubscribe($id);
				remove_schedule($db, $uc, $id, COMMAND_UPDATE);
			}
		}
	}
}

$allgroups = array();
$minsetsize_pref = get_pref($db, 'minsetsize', $userID, 0);
$maxsetsize_pref = get_pref($db, 'maxsetsize', $userID, 0);

try {
	if (isset($_POST['export'])) {
		header('Content-Type: text/html/force-download');
        header('Content-Disposition: attachment; filename=urd_group_settings.xml');
        $xml = new urd_xml_writer('php://output');
        $xml->write_newsgroups($db);
        $xml->output_xml_data();
		die;
	} else if (isset($_POST['load_settings']) && isset ($_FILES['filename']['tmp_name']) && $isadmin) {
        verify_challenge($_POST['challenge']);
        $xml = new urd_xml_reader($_FILES['filename']['tmp_name']);
		$groups = $xml->read_newsgroup_settings($db);
		if ($groups != array()) {
			clear_all_groups($db, $userID);
			set_all_groups($db, $groups, $userID);
		} else
			$__message[] = $LN['settings_notfound'];
	} else {
		if (isset($_POST['action']) && $isadmin) {
			verify_challenge($_POST['challenge']);
			update_ng_subscriptions ($db, $uc, $userID);
		}	
		if (isset($_POST['action'])) {
			verify_challenge($_POST['challenge']);
			update_user_ng_info($db, $userID);
		}
	}

	$res = build_newsgroup_query($db, $userID, $retvals);
	$unsubscribed = $retvals[0];
	$order = post_form('order', 'name');
	$order_dir = post_form('order_dir', '');
    $search = utf8_decode(trim(get_request('search', '')));
    if ($search == (html_entity_decode("<{$LN['search']}>")))
        $search = '';
	$search_all = post_form('search_all', '');

	$info = build_newsgroup_skipper($db, $userID);
	$pages = $info[0];
	$lastpage = $info[1];
	$currentpage = $info[2];
    $def_exp = get_config($db, 'default_expire_time');

	foreach ($res as $row) {
		$thisng = array();
		$id = $row['ID'];
		$active = $row['active'];
		$description = trim (str_replace('?', '', $row['description']));
		$thisng['id'] = $id;
		$thisng['active_val'] = $active;
		$thisng['description'] = $description;

		$thisng['name'] = shorten_newsgroup_name ($row['name'], 0);
	    if ($active == 0)
            $thisng['expire'] = $def_exp;
        else 
            $thisng['expire'] = $row['expire'];
		$thisng['postcount'] = $row['postcount'];
		$lastupdated = $row['timestamp'];
		$refresh_time = $row['refresh_time'];

		$refresh_period = $row['refresh_period'];
		$thisng['description'] = $description;

		if ($refresh_period > 0) {
			$time1 = floor($refresh_time / 60);
			$time2 = sprintf('%02d', floor($refresh_time % 60));
		} else
			$time1 = $time2 = '';

		$select = $refresh_period;

		if ($lastupdated == 0) 
			$lastupdated = '-';
		else {
			$lastupdated = time() - $lastupdated;
			$lastupdated = readable_time($lastupdated, 'largest_two');
		}
		$thisng['lastupdated'] = $lastupdated;

		$thisng['select'] = $select;
		$thisng['time1'] = $time1;
		$thisng['time2'] = $time2;
		$sql = "visible, minsetsize, maxsetsize FROM usergroupinfo WHERE groupid='$id' AND userid='$userID'";
		$row2 = $db->select_query($sql, 1);

		if ($row2 === FALSE) {
			$thisng['visible'] = 1;
			$thisng['minsetsize'] = $minsetsize_pref;
			$thisng['maxsetsize'] = $maxsetsize_pref;
		} else {
			$thisng['visible'] = $row2[0]['visible'] === NULL ? 1 : $row2[0]['visible'];
			$thisng['minsetsize'] = $row2[0]['minsetsize'] === NULL ? 0: $row2[0]['minsetsize'] ;
			$thisng['maxsetsize'] = $row2[0]['maxsetsize'] === NULL ? 0: $row2[0]['maxsetsize'] ;
		}
		$allgroups[] = $thisng;
	}
} catch (exception $e) {
	fatal_error($e->getMessage());
}
//$challenge = set_challenge();
if (isset($__message)) 
	$smarty->assign('__message',                $__message);

list($pkeys, $ptexts) = $periods->get_periods();

$message = '';
if ($isadmin && !$urdd_online)
    $message = $LN['enableurddfirst'];
$uc->disconnect();

init_smarty($LN['ng_title']);
$smarty->assign('periods_texts',	$ptexts);
$smarty->assign('urdd_online',	    (int)$urdd_online);
$smarty->assign('periods_keys',		$pkeys);
$smarty->assign('message',		$message);

$smarty->assign('NG_SUBSCRIBED', 	NG_SUBSCRIBED);
$smarty->assign('order',		    $order);
$smarty->assign('search',		    $search);
$smarty->assign('search_all',		($search_all == '')?0:1);
$smarty->assign('isadmin',		    (int)$isadmin);
$smarty->assign('order_dir',		$order_dir);
$smarty->assign('unsubscribed',		$unsubscribed);
$smarty->assign('pages',		    $pages);
$smarty->assign('currentpage',		$currentpage);
$smarty->assign('lastpage',		    $lastpage);
$smarty->assign('offset',		    post_form('offset',0));
$smarty->assign('allgroups', 		$allgroups);
$smarty->assign('maxstrlen',		$prefs['maxsetname']/2);
$smarty->assign('referrer', 		basename(__FILE__, '.php'));
	
$smarty->display('newsgroups.tpl');

?>
